'''
Created on 2009-9-14

@author: loudly
'''
import django.template.loader as loader
from django import newforms as forms
import django.core.urlresolvers as urlresolvers
from django import http

import google.appengine.ext.db as db

from models import Game
from embedView import EmbedView
from embedView import NewGameForm
from utils.advancedforms import MultipleCharField
from OfficialMahjongUtils import seatRotate

class OfficialMahjongNewGameForm(NewGameForm):
    
    totalSessions = forms.IntegerField(initial = 1)
    
    def __init__(self, *args, **kwargs):        
        
        super(OfficialMahjongNewGameForm, self).__init__(4, *args, **kwargs)
        
        for i in range(0, 4) :
            self.fields['playerArr'].fields[i].required = True        

class OfficialMahjongPlayingControlForm(forms.Form):
    
    player0Name = forms.CharField(required = True)
    player1Name = forms.CharField(required = True)
    player2Name = forms.CharField(required = True)
    player3Name = forms.CharField(required = True)
    
    player0Fan = forms.IntegerField(required = True)
    player1Fan = forms.IntegerField(required = True)
    player2Fan = forms.IntegerField(required = True)
    player3Fan = forms.IntegerField(required = True)
    
    def __init__(self, *args, **kwargs):
        
        super(OfficialMahjongPlayingControlForm, self).__init__(*args, **kwargs)    

class OfficialMahjongEmbedView(EmbedView):
    '''
    classdocs
    '''
    
    gameName = 'official_mahjong'
    gameTexts = {
            'en' : {
                'displayName' : u'Official Mahjong',
                'directionNameEast' : u'East', 
                'directionNameSouth' : u'South', 
                'directionNameWest' : u'West', 
                'directionNameNorth' : u'North', 
            }
        }
    
    windToDirectionName = {'east' : 'directionNameEast',
                           'south' : 'directionNameSouth',
                           'west' : 'directionNameWest',
                           'north' : 'directionNameNorth'}
    
    def __init__(selfparams):
        '''
        Constructor
        '''
    
    @staticmethod
    def index(request):
        return http.HttpResponse('I am here')
    
    @staticmethod
    def gameListView(game):
        ret = ''
        ret += '%s<br>' % game.name
        ret +=  'Will play for %s sessions, already %s sessions<br>' % \
            (game.totalSessions, game.roundsForNow)
        
        ret += 'Players are : %s' % (', '.join(game.players))
        ret += '<br />\n'
        
        for session in game.sessions :
            ret += '&nbsp;&nbsp;Session %s : start at %s, played %s hands<br />' % \
                (session.roundNumber, session.startTime, session.roundsForNow)
            
            for hand in session.hands.order('roundNumber') :
                ret += '&nbsp;&nbsp;&nbsp;&nbsp;'
                ret += 'Hand %s : start at %s<br />' % \
                    (hand.roundNumber, hand.startTime) 
        
        return OfficialMahjongEmbedView._newEmbedReturnValue(content = ret)
    
    def newGame(self, request):
        
        if request.method == 'POST': # If the form has been submitted...
            newGameForm = OfficialMahjongNewGameForm(request.POST)
            
            if newGameForm.is_valid():
                
                from OfficialMahjongModels import OfficialMahjongGame
                
                game = OfficialMahjongGame(name = newGameForm.clean_data['name'], 
                                           gameType = 'official_mahjong',
                                           players = newGameForm.clean_data['playerArr'],
                                           totalSessions = newGameForm.clean_data['totalSessions'],
                                           sumScores = [0, 0, 0, 0],
                                           roundsForNow = 0)
                game.put()
                
                return self._newEmbedReturnValue(action = self.ACTION_REDIRECT, 
                                                 target = urlresolvers.reverse('views.play', 
                                                                               kwargs={
                                                                                    'gameName': 'official_mahjong',
                                                                                    'gameKeyStr': str(game.key()) }
                                                                               ))
            else :
                if 'name'  in newGameForm.errors and newGameForm.errors['name'] :
                    del newGameForm.errors['name'][:]
                    newGameForm.errors['name'].append('The game must have a name')
                
                if 'playerArr' in newGameForm.errors and newGameForm.errors['playerArr'] :
                    del newGameForm.errors['playerArr'][:]
                    newGameForm.errors['playerArr'].append('Enter names for all 4 players')
                
                if 'totalSessions' in newGameForm.errors and newGameForm.errors['totalSessions'] :
                    del newGameForm.errors['totalSessions'][:]
                    newGameForm.errors['totalSessions'].append('Enter the number of sessions')
        else:
            newGameForm = OfficialMahjongNewGameForm() 
        ret = ''
        
        template_values = {
            'baseFormContent': self._newGameInputs(newGameForm)['content'],
            'form': newGameForm
        }
        
        ret += loader.render_to_string('OfficialMahjong/newGame.html', template_values)
        
        return self._newEmbedReturnValue(content = ret)
    
    def _getWindKey(self, number):
        if number % 4 == 0 : return 'directionNameEast'
        if number % 4 == 1 : return 'directionNameSouth'
        if number % 4 == 2 : return 'directionNameWest'
        if number % 4 == 3 : return 'directionNameNorth'
    
    def _controlBlock(self, playerNameArr, gameKey, sessionNumber, handNumber, hand):
        ret = ''
        
        form = OfficialMahjongPlayingControlForm()
        
        for i in range(0, 4) :
            
            if hand :
                form.fields['player%sFan' % i].initial = hand.fans[i]
                form.fields['player%sName' % i].initial = hand.players[i]
            else :
                form.fields['player%sFan' % i].initial = None
                form.fields['player%sName' % i].initial = playerNameArr[i]
            
        template_values = {
            'form': form, 
            'roundWind' : self.gameText(self._getWindKey(handNumber / 4)),
            'seatWind' : self.gameText(self._getWindKey(handNumber % 4)),
            'handNumber' : handNumber,
            'sessionNumber' : sessionNumber,
            'modifying' : (hand != None), 
            'gameKey' : gameKey, 
        }
        
        ret += loader.render_to_string('OfficialMahjong/playingControl.html', template_values)
        
        return self._newEmbedReturnValue(content = ret)
    
    def _sessionBlock(self, game, session, sessionNumber):
        
        ret = ''
        if session :
            players = session.players
        else :
            players = game.players
        
        if session and session.roundsForNow > 0:
            firstHand = session.hands.order('roundNumber').fetch(1)[0]
            players = firstHand.players
        
        playerSumFanArr = [0, 0, 0, 0]
        handsArr = []
        playerPosition = {}
        
        for i in range(0, 4) :
            playerPosition[players[i]] = i
        
        if session :
            for i in range(0, 4) :
                playerSumFanArr[playerPosition[session.players[i]]] = session.sumFans[i]
        
            for hand in session.hands.order('-roundNumber') :
                currentPlayers = hand.players
                currentFansArr = [0, 0, 0, 0]
                 
                for i in range(0, 4) :
                    currentFansArr[playerPosition[currentPlayers[i]]] = hand.fans[i]
                    
                arr = {}
                arr['roundWindName'] = self.gameText(self.windToDirectionName[hand.roundWind])
                arr['seatWindName'] = self.gameText(self.windToDirectionName[hand.seatWind])
                arr['fansArr'] = currentFansArr
                arr['handNumber'] = hand.roundNumber
                
                handsArr.append(arr)
        
        template_values = {
            'players' : players,
            'playerSumFanArr' : playerSumFanArr,
            'sessionNumber' : sessionNumber,
            'gameKey' : game.key(),  
            'handsArr' : handsArr, 
        }
        
        ret += loader.render_to_string('OfficialMahjong/sessionBlock.html', template_values)
        
        return self._newEmbedReturnValue(content = ret)
    
    def _gameBlock(self, game):
        
        sessionsArr = []
        ret = ''
        
        for session in game.sessions.order('-roundNumber') :
            arr = {}
            
            arr['scoresArr'] = session.sumScores
            arr['sessionNumber'] = session.roundNumber
            
            sessionsArr.append(arr)
        
        template_values = {
            'players' : game.players,
            'playerSumScoresArr' : game.sumScores,
            'gameKey' : game.key(),
            'sessionsArr' : sessionsArr,
        }
        
        ret += loader.render_to_string('OfficialMahjong/gameBlock.html', template_values)
        
        return self._newEmbedReturnValue(content = ret)
            
    def play (self, request, gameKey):
        game = db.get(gameKey)
        
        controlContent = ''
        
        lastSession = None
        lastHand = None
        
        if game.roundsForNow > 0 :
            lastSession = game.sessions.order('-roundNumber').fetch(1)[0]
        
        if lastSession != None and lastSession.roundsForNow > 0 :
            lastHand = lastSession.hands.order('-roundNumber').fetch(1)[0]            
        
        controlBlock = ''
        sessionBlock = ''
        gameBlock = ''
        
        if 'session' in request.GET:
            sessionNumber = int(request.GET['session'])
            session = game.sessions.filter('roundNumber =', sessionNumber).fetch(1)[0]
            
            ret = self._sessionBlock(game, session, sessionNumber)
            if ret['action'] == None :
                sessionBlock = ret['content']
            
            if 'hand' in request.GET :
                handNumber = int(request.GET['hand'])
                hand = session.hands.filter('roundNumber =', handNumber).fetch(1)[0]
                
                ret = self._controlBlock(None, gameKey, sessionNumber, handNumber, hand)
                if ret['action'] == None :
                    controlBlock = ret['content']
            
        elif game.finished :
            # game is already finished
            template_values = {
                'gameFinished' : True,  
            }
            
            controlBlock = loader.render_to_string('OfficialMahjong/finished.html', template_values)
            
            if game.totalSessions == 1 and lastSession :
                ret = self._sessionBlock(game, lastSession, 0)
                if ret['action'] == None :
                    sessionBlock = ret['content']
            
        else :
            if lastSession != None and lastSession.finished :
                # last session just finished, ask if to start new session
                template_values = {
                    'lastSessionNumber' : lastSession.roundNumber,
                    'nextSessionNumber' : lastSession.roundNumber + 1, 
                    'gameKey' : game.key(), 
                    'gameFinished' : False,  
                }
                
                controlBlock = loader.render_to_string('OfficialMahjong/finished.html', template_values)
                
                ret = self._sessionBlock(game, lastSession, lastSession.roundNumber)
                if ret['action'] == None :
                    sessionBlock = ret['content']
            else :
                # display normal playing form, can be filled with scores
                if lastSession == None or lastSession.roundsForNow == 0 :
                    # arrange seats with initial player list
                    sessionNumber = 0
                    if lastSession != None :
                        sessionNumber = lastSession.roundNumber
                     
                    ret = self._controlBlock(game.players, gameKey, sessionNumber, 0, None)
                    if ret['action'] == None :
                        controlBlock = ret['content']
                    
                    ret = self._sessionBlock(game, lastSession, sessionNumber)
                    if ret['action'] == None :
                        sessionBlock = ret['content']
                    
                elif  lastSession.roundsForNow % 4 == 0 :
                    # change seats according to last hand
                    players = seatRotate(lastSession.roundsForNow, lastHand.players)
                    
                    ret = self._controlBlock(players, gameKey, lastSession.roundNumber, lastSession.roundsForNow, None)
                    if ret['action'] == None :
                        controlBlock = ret['content']
                    
                    ret = self._sessionBlock(game, lastSession, lastSession.roundNumber)
                    if ret['action'] == None :
                        sessionBlock = ret['content']

                else :
                    # just copy last hand's seat
                    ret = self._controlBlock(lastHand.players, gameKey, lastSession.roundNumber, lastSession.roundsForNow, None)
                    if ret['action'] == None :
                        controlBlock = ret['content']
                    
                    ret = self._sessionBlock(game, lastSession, lastSession.roundNumber)
                    if ret['action'] == None :
                        sessionBlock = ret['content']
        
        ret = self._gameBlock(game)
        gameBlock = ret['content']
        
        return self._newEmbedReturnValue(content = {'control' : controlBlock, 'round_0' : sessionBlock, 'round_1' : gameBlock, 'game' : game, }, 
                                         layout = (EmbedView.LAYOUT_PLAY_HORIZONTAL, 2),)
